# -*- coding: UTF-8 -*-
#实现减少3D打印在边缘处的物料堆积。
#实现方法是处理GCode ，在挤出量不变的情况下，在打印线条末端提前结束挤出。
#程序运行的参数说明：
# tail :提前结束长度，单位是毫米
# minlength: 最小线条长度，小于该长度的线条不做处理。
from math import sqrt
import sys
infile=sys.argv[1]
outfile=sys.argv[2]
#outfile="top1.gcode"
prex:float=0.0
prey:float=0.0
tail:float=sys.argv[3]
minlength:float=sys.argv[4]

def process(ln:str,cmd:list,out:list):
    global prex,prey
    newx,newy=prex,prey
    E=""
    for p in cmd[1:4]:
        if p[0]in 'Xx':
            newx=float(p[1:])
            X=p
        elif p[0] in 'Yy':
            newy=float(p[1:])
            Y=p
        elif p[0] in 'Ee':
            E=p
    a=newx-prex
    b=newy-prey
    c=sqrt(a**2+b**2)
    if c<minlength:
        out.append(ln)
        prex,prey=newx,newy
        return
    c1=c-tail
    a1=c1/c*a
    b1=c1/c*b
    x1=prex+a1
    y1=prey+b1
    out.append(" ".join([cmd[0],"X"+str(round(x1,3)),"Y"+str(round(y1,3)),E]))
    out.append(" ".join([cmd[0],X,Y+"\n"]))
    prex,prey=newx,newy

with open(infile,"r") as fin:
    lns=fin.readlines()


out=[]
for ln in lns:
    cmds=ln.split(";")[0]
    cmd=cmds.split(" ")
    if cmd[0]!="G1":
        out.append(ln)
        continue
    if "X" in ln and "Y" in ln and "E" in cmds:
        process(ln,cmd,out)
        continue
    out.append(ln)
    newx=prex
    newy=prey
    for p in cmd[1:]:
        if not p :continue
        if p[0]in 'Xx':
            newx=float(p[1:])
            X=p
        elif p[0] in 'Yy':
            newy=float(p[1:])
            Y=p
    prex,prey=newx,newy

with open(outfile,'w') as fo:
    fo.writelines(out);    